<template>
  <div id="hm-wuziqi2">
    <div id="info"></div>
    <div id="root"></div>
  </div>
</template>

<script>
export default {
  name: 'nav',
  data () {
    return {
    }
  },
  mounted () {
    var Gobang = (function () {
      // 定义私有变量 roundDirectArr
      var arr = [1, -1, 0]
      var roundDirectArr = []
      arr.forEach(v => roundDirectArr.push([v, 1]))
      roundDirectArr.push([-1, 0])

      // 定义 Gobang 的方法集
      class GobangUtil {
        getProps (x, y) {
          return 'x' + x + 'y' + y
        }

        getColor (board, x, y) {
          return board[this.getProps(x, y)]
        }

        // 返回每个方向的颜色值相同的棋子数
        getDirectSameColorNum (x, y, board, direct) {
          var result = 0
          var bindGetcolor = this.getColor.bind(this, board)
          var activeColor = bindGetcolor(x, y)

          for (var i = 1; i < 5; i++) {
            var nextColor = bindGetcolor(x + i * direct[0], y + i * direct[1])
            if (activeColor === nextColor) { result++ } else { break }
          }
          return result
        }

        // 判断单个轴(两个方向)是否成立
        checkSingleDirect (x, y, board, direct) {
          var leftDirect = direct
          var rightDirect = direct.map(v => -v)
          var getNum = this.getDirectSameColorNum.bind(this, x, y, board)

          return (getNum(leftDirect) + 1 + getNum(rightDirect)) >= 5
        }

        // 判断 4 个轴中是否有一个成立
        checkRoundDirect (x, y, board, roundDirect) {
          return roundDirect.some(direct => this.checkSingleDirect(x, y, board, direct))
        }
      }

      // 定义 Gobang
      class Gobang extends GobangUtil {
        constructor (callback) {
          super()
          var board = new Proxy({}, {
            get: function (target, property) {
              if (property in target) {
                return target[property]
              } else {
                return 0
              }
            }
          })

          this.board = board
          this.callback = callback
          this.playChess = this.palyChess.bind(this)
        }

        palyChess (x, y, colorNumber) {
          this.board[super.getProps(x, y, colorNumber)] = colorNumber

          var isWin = super.checkRoundDirect(x, y, this.board, roundDirectArr)
          isWin ? this.callback.end(colorNumber) : this.callback.keep(colorNumber)
        }
      }

      return Gobang
    })()
    var Game = (function () {
      var chessColor = 2
      var isWin = false
      var ele = document.getElementById('root')

      function instantGobang (onEnd, onKeep) {
        // 生成 Gobang 实例，定义游戏结束与继续事件
        var mygobang = new Gobang({
          end (color) {
            onEnd(color)
            isWin = true
          },
          keep (color) {
            onKeep(color)
          }
        })

        return mygobang
      }

      function renderTpl (num) {
        var tpl
//          coordArr = [],
        var htm = ''
        var arr = [...Array(num).keys()]
        console.log('arr', arr)
        var rwidth = ele.clientWidth
          // console.log(rwidth)
        var swidth = parseInt((rwidth / num), 10) + 'px'
        var cwidth = parseInt((rwidth / num / 1.2), 10) + 'px'
        tpl = (coord, color) => (`
          <div class="square" style="width:${swidth};height:${swidth}">
            <div class="circle ${color === 1 ? color : ''}" data-coord="${coord}" style="width:${cwidth};height:${cwidth}"></div>
          </div>
        `)
        arr.forEach(v => arr.forEach(e => { htm += tpl([e, v]) }))
        return htm
      }

      function renderHtm (tpl) {
        ele.innerHTML = tpl
      }

      function bindEvent (mygobang) {
        ele.addEventListener('click', (e) => {
          if (isWin) {
            return
          }
          var target = e.target
          if (target.className.includes('circle') && target.classList.length === 1) {
            chessColor = 3 - chessColor
            var coord = target.getAttribute('data-coord').split(',')
            target.classList.add(chessColor === 1 ? 'white' : 'black')
            mygobang.palyChess(+coord[0], +coord[1], chessColor)
          }
        })
      }

      return {
        start (num, {onEnd, onKeep}) {
          // 渲染棋盘
          renderHtm(renderTpl(num))

          // 生成 gobang 实例并绑定事件
          bindEvent(instantGobang(onEnd, onKeep))
        }
      }
    })()

    Game.start(15, {
      onEnd (color) {
        alert(`游戏结束, ${color === 1 ? '白子' : '黑子'}胜利`)
      },
      onKeep (color) {
        document.getElementById('info').innerHTML = `${color !== 1 ? '白子' : '黑子'}回合`
      }
    })
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
  #info {
    margin-bottom: 10px;
    padding-top: 10px;
    height: 50px;
    line-height: 50px;
    color: #fff;
    font-size: 18px;
    text-align: center;
    text-shadow: 1px 1px #000;

  }

  #root {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    width: 90%;
    max-width: 320px;
    margin: 0 auto;
    padding: 0px;
    border-bottom: 1px solid rgba(0,0,0,.4);
    border-right: 1px solid rgba(0,0,0,.4);
    box-shadow: 0 0 30px #333;
    background: rgb(238, 238, 238);
    border-radius: 10px;
    overflow: hidden;
    user-select:none;
    -webkit-tap-highlight-color:rgba(255,0,0,0);
  }

  .square {
    position: relative;
    flex-grow: 1;
    margin: 0;
    box-shadow: 1px 1px 1px rgba(0,0,0,.4) inset;
  }
  .circle {
    position: absolute;
    top: 0;
    left: 0;
    transform: translate(-50%, -50%);
    border-radius: 50%;
  }

  .white {
    background: #fff;
    border: 1px solid #ccc;
    box-shadow: 0 0 3px #ccc,
    0 2px 2px #eee inset;
  }

  .black {
    background: #000;
    border: 1px solid #000;
    box-shadow: 0 0 3px #ccc,
    0 2px 2px #222 inset;
  }
</style>
